if not actions then
	actions = {}
end

if not actions.Exit then

dofile (getScriptPath() .. "\\..\\lib\\lib.lua")
dofile (getScriptPath() .. "\\..\\lib\\orders.lua")


actions.action_loaded = {}


function actions:Break(instrument, not_save)
	if type(instrument) == "string" then
		instrument = lib:GetInstrument(instrument)
		if not instrument then return end
	end

	if not not_save then
		self:SaveAction("break", instrument)
	end

	orders.log("Break Kill Orders")
	if not not_save then
		if instrument then
			message("Break " .. instrument.code)
		else
			message("Break All")
		end
	end
	
	for _, order in pairs(orders:GetActivatedStops(instrument)) do
		orders:KillOrder(orders:GetLimit(order.co_order_num))
	end

	--local order, state
	--for i = getNumberOf("orders") - 1, 0, -1 do
	--	order = orders:IsOrder(getItem("orders", i))
	--	if order and (not instrument
	--					or instrument.class_code == order.class_code
	--					and instrument.code == order.sec_code)
	--	then
	--		state = bit.band(order.flags, 3)
	--		if state == 1 then
	--			orders:KillOrder(order)
	--		end
	--	end
	--end
end


function actions:Half(instrument)
	if type(instrument) == "string" then
		instrument = lib:GetInstrument(instrument)
		if not instrument then return end
	end
	
	self:SaveAction("half", instrument)
	
	orders.log("Half Kill Stop Orders")
	if instrument then
		message("Half " .. instrument.code)
	else
		message("Half All")
	end
	
	self:Break(instrument, true)
	
	local stop_pos = orders:GetPosition(instrument.code)
	local groups, stops = orders:GetActiveStopGroups(instrument.code)
	local half = math.abs(stop_pos) / 2
	--local half = 1		-- test
	local done = 0
	local is_long
	local tev
	local sl
	local transaction
	
	for j, group in ipairs(groups) do
	--for i = #numeric_table, 1, -1 do
		for i, stop in ipairs(groups[j]) do
			--message("Half " .. j .. " " .. i .. " " .. groups.count .. " " .. done .. " " .. stop.qty .. " " .. stop.condition_price)
			
			if groups.count > 1 and done + stop.qty <= half then
				message("ExecuteStopOrder " .. j .. " " .. i .. " " .. orders:GetTakePrice(stop))
				sl = orders:GetStopPrice(stop)
				is_long = bit.test(stop.flags, 2)		-- position side, not the order
				transaction = orders:ExecuteStopOrder(stop)
				if transaction then
					tev = transaction.price
					done = done + stop.qty
					groups.count = groups.count - 1
					stops[stop.order_num] = nil
				end
			end
		end
	end
	--[[
	if sl and tev and is_long ~= nil and (tev > sl == is_long) then
		orders:ShiftEven(stops, sl, tev, math.abs(stop_pos), done)
		--orders:ShiftEven(instrument.code, sl, tev, math.abs(stop_pos), done)
	else
		fail("Half ShiftEven no param: sl=" .. tostring(sl) .. " tev=" .. tostring(tev) .. " is_long=" .. tostring(is_long))
	end
	--]]
end


function actions:Exit(instrument)
	if type(instrument) == "string" then
		instrument = lib:GetInstrument(instrument)
		if not instrument then return end
	end
	
	self:SaveAction("exit", instrument)
	
	orders.log("Exit Kill Stop Orders")
	
	if instrument then
		message("Exit " .. instrument.code)
	else
		message("Quit")
	end
	
	self:Break(instrument, true)
	
	for _, order in pairs(orders:GetActiveStops(instrument)) do
		orders:ExecuteStopOrder(order)
	end
end


function actions:Quit()
	self:Exit()
end


function actions:Shift(instrument)
	if type(instrument) == "string" then
		instrument = lib:GetInstrument(instrument)
		if not instrument then return end
	end
	
	self:SaveAction("shift", instrument)
	
	orders.log("Shift Limit Orders")
	
	--if instrument then
	--	message("Shift " .. instrument.code)
	--else
	--	message("Shift All")
	--end
	
	local stops = orders:GetActivatedStops(instrument)
	local ret
	
	for num, order in pairs(orders:GetLimits(instrument)) do
		for _, stop in pairs(stops) do
			if stop.co_order_num == num then
				--order = nil
				order.lm__ = order.price
				if stop.condition_price2 and stop.condition_price2 > 0 then
					order.sl__ = stop.condition_price2
					order.tp__ = stop.condition_price
				else
					order.sl__ = stop.condition_price
				end
				order.stop_qty__ = order.qty
				break
			end
		end
		if order then
			--orders.log("Shift order", order)
			--message("Shift order " .. order.order_num)
			ret = orders:ShiftLimit(order) or ret
		end
	end
	
	return ret
end


function actions:SaveAction(action, instrument)
	if orders.do_save and action then
		if type(instrument) == "string" then
			instrument = lib:GetInstrument(instrument)
			if not instrument then return end
		end
	
		local file = lib.path.orders .. "action."
		for i = 0, 9 do
			if not lib:exists(file .. i) then
				local data = {
					action = action,
					id = i .. "_" .. math.random(100000, 999999),
					seconds = lib:tickseconds(),
				}
				if instrument then
					data.sec_code = instrument.code
				end
				self.action_loaded[data.id] = data.seconds	-- self loading lock
				lib:SaveLabels(file .. i, data)
				break
			end
		end
	end
end
	
function actions:LoadAction()
	if self.wait_exit then
		local pos = orders:GetPosition(self.wait_exit.code, self.wait_exit.is_exit)
		if not self.wait_exit.code or pos == 0 then
			self.wait_exit = nil
		else
			return true
		end
	end
	
	local ret
	local now = lib:tickseconds()
	local file = lib.path.orders .. "action."
	
	for i = 0, 9 do
		local data = lib:LoadLabels(file .. i)
		if data then
			if now - int(data.seconds) >= -1 and now - int(data.seconds) < lib.global.file_ttl then
				if not self.action_loaded[data.id] then
					message("not loaded " .. data.id .. " " .. lib:toline(self.action_loaded))
					self.action_loaded[data.id] = int(data.seconds)
					ret = true
					
					local do_save = orders.do_save
					orders.do_save = nil
					
					if data.action == "exit" then
						self.wait_exit = {code = data.sec_code, is_exit = true}
						self:Exit(data.sec_code)
					elseif data.action == "break" then
						self.wait_exit = {code = data.sec_code, is_exit = false}
						self:Break(data.sec_code)
					elseif data.action == "half" then
						self:Half(data.sec_code)
					elseif data.action == "quit" then
						self:Exit()
					elseif data.action == "shift" then
						message("Shift " .. tostring(data.sec_code))
						self:Shift(data.sec_code)
					else
						ret = data
					end
					
					orders.do_save = do_save
				end
			else
				lib:remove(file .. i)
			end
		end
		if ret then break end
	end
	
	for k, v in pairs(self.action_loaded) do
		 if now - v > lib.global.file_ttl then
			self.action_loaded[k] = nil
		 end
	end
	
	return ret
end


end -- of file
